// ArkUICustomNode.h
// 自定义绘制组件示例

#ifndef MYAPPLICATION_ARKUICUSTOMNODE_H
#define MYAPPLICATION_ARKUICUSTOMNODE_H

#include <native_drawing/drawing_brush.h>
#include <native_drawing/drawing_canvas.h>
#include <native_drawing/drawing_path.h>

#include <multimedia/image_framework/image/image_source_native.h>
#include <multimedia/image_framework/image/pixelmap_native.h>

#include "ArkUINode.h"
#include <string>
#include "rlottie.h"
#include <native_drawing/drawing_error_code.h>
#include <cstdint>
#include <cmath>
#include <string>
#include "napi/native_api.h"
#include <bits/alltypes.h>
#include <multimedia/image_framework/image_mdk_common.h>
#include <multimedia/image_framework/image_pixel_map_mdk.h>
#include <native_window/external_window.h>
#include <native_drawing/drawing_bitmap.h>
#include <native_drawing/drawing_color.h>
#include <native_drawing/drawing_color_filter.h>
#include <native_drawing/drawing_canvas.h>
#include <native_drawing/drawing_pen.h>
#include <native_drawing/drawing_pixel_map.h>
#include <native_drawing/drawing_brush.h>
#include <native_drawing/drawing_path.h>
#include <native_drawing/drawing_rect.h>
#include <native_drawing/drawing_register_font.h>
#include <native_drawing/drawing_filter.h>
#include <native_drawing/drawing_font.h>
#include <native_drawing/drawing_font_collection.h>
#include <native_drawing/drawing_sampling_options.h>
#include <native_drawing/drawing_text_blob.h>
#include <native_drawing/drawing_text_declaration.h>
#include <native_drawing/drawing_text_typography.h>
#include <native_drawing/drawing_types.h>
#include <native_drawing/drawing_typeface.h>
#include "native_drawing/drawing_image.h"
#include <chrono>
#include <iostream>
#include <rlottie_capi.h>
#include <hilog/log.h>
#include "Getrlottie.h"

namespace NativeModule {

class ArkUICustomNode : public ArkUINode {
public:
    Glottie *Lalrlottie = new Glottie;
    // 使用自定义组件类型ARKUI_NODE_CUSTOM创建组件。
    ArkUICustomNode(float width,float height)
        : ArkUINode((NativeModuleInstance::GetInstance()->GetNativeNodeAPI())->createNode(ARKUI_NODE_CUSTOM))
    {
        // 注册自定义事件监听器。
        nativeModule_->addNodeCustomEventReceiver(handle_, OnStaticCustomEvent);
        // 声明自定义事件并转递自身作为自定义数据。
        nativeModule_->registerNodeCustomEvent(handle_, ARKUI_NODE_CUSTOM_EVENT_ON_DRAW, 0, this);

        Lalrlottie->InitFormFile(FileName);
        Lalrlottie->PrintInfo();
        
        
        ArkUI_NumberValue valueHeight[] = {{.f32 = height}};
        ArkUI_AttributeItem item = {valueHeight, 1};
        nativeModule_->setAttribute(handle_, NODE_HEIGHT, &item);
        
        ArkUI_NumberValue valueWidth[] = {{.f32 = width}};
        item = {valueWidth, 1};
        nativeModule_->setAttribute(handle_, NODE_WIDTH, &item);
        
        width_ = width * 3.25;
        height_ = height * 3.25;
        
        
        OH_Pixelmap_InitializationOptions *options;
        OH_PixelmapInitializationOptions_Create(&options);
        OH_PixelmapInitializationOptions_SetWidth(options, width_);
        OH_PixelmapInitializationOptions_SetHeight(options, height_);
        OH_PixelmapInitializationOptions_SetPixelFormat(options, PIXEL_FORMAT_RGBA_8888);
        
        uint8_t *resces = reinterpret_cast<uint8_t *>(Lalrlottie->RenderFrame(FrameNum, width_, height_));
        
        rect = OH_Drawing_RectCreate(0, 0, width_, height_);
        
        OH_PixelmapNative_CreatePixelmap(resces, width_ * height_ * 4, options, &resPixMap_);
        lastPixmap_ = OH_Drawing_PixelMapGetFromOhPixelMapNative(resPixMap_);
    }

    ~ArkUICustomNode() override
    {
        // 反注册自定义事件监听器。
        nativeModule_->removeNodeCustomEventReceiver(handle_, OnStaticCustomEvent);
        // 取消声明自定义事件。
        nativeModule_->unregisterNodeCustomEvent(handle_, ARKUI_NODE_CUSTOM_EVENT_ON_DRAW);
        delete Lalrlottie;
    }

    void setFrameNum()
    {
        if (FrameNum >= 25) {
            FrameNum = 0;
        } else {
            FrameNum++;
        }
        nativeModule_->markDirty(handle_, NODE_NEED_RENDER);
    }

private:
    std::string FileName = "/data/storage/el2/base/haps/entry/files/lottie_1_1.json";
    int32_t FrameNum = 0;
    float width_ = 0;
    float height_ = 0;
    OH_PixelmapNative *resPixMap_ = nullptr;
    OH_Drawing_PixelMap* lastPixmap_ = nullptr;
    OH_Drawing_Rect *rect;
    static void OnStaticCustomEvent(ArkUI_NodeCustomEvent *event)
    {
        // 获取组件实例对象，调用相关实例方法。
        auto customNode = reinterpret_cast<ArkUICustomNode *>(OH_ArkUI_NodeCustomEvent_GetUserData(event));
        auto type = OH_ArkUI_NodeCustomEvent_GetEventType(event);
        switch (type) {
            case ARKUI_NODE_CUSTOM_EVENT_ON_DRAW :
                customNode->OnDraw(event);
                break;
            default :
                break;
        }
    }

    // 自定义绘制逻辑。
    void OnDraw(ArkUI_NodeCustomEvent *event)
    {
        
        auto drawContext = OH_ArkUI_NodeCustomEvent_GetDrawContextInDraw(event);
        // 获取图形绘制对象。
        auto drawCanvas = reinterpret_cast<OH_Drawing_Canvas *>(OH_ArkUI_DrawContext_GetCanvas(drawContext));
        // 获取组件大小。
        auto size = OH_ArkUI_DrawContext_GetSize(drawContext);
        
        uint8_t *pixel = reinterpret_cast<uint8_t *>(Lalrlottie->RenderFrame(FrameNum, width_, height_));
        
        auto now = std::chrono::high_resolution_clock::now();
        auto startTime = std::chrono::time_point_cast<std::chrono::nanoseconds>(now).time_since_epoch();
        
        //下面这个是pixmap进行绘制的
        OH_Drawing_SamplingOptions* drawOption =  OH_Drawing_SamplingOptionsCreate(FILTER_MODE_LINEAR, MIPMAP_MODE_NEAREST);
        OH_PixelmapNative_WritePixels(resPixMap_, pixel, height_ * width_ * 4);
        lastPixmap_ = OH_Drawing_PixelMapGetFromOhPixelMapNative(resPixMap_);
        OH_Drawing_CanvasDrawPixelMapRect(drawCanvas, lastPixmap_, rect, rect, drawOption);
        
        // 释放资源
        OH_Drawing_CanvasDetachBrush(drawCanvas);
        
        now = std::chrono::high_resolution_clock::now();
        auto endTime = std::chrono::time_point_cast<std::chrono::nanoseconds>(now).time_since_epoch();
        DRAWING_LOGE("\n\n\n单次解析第%{public}2.d帧,用时%{public}5.2fms", FrameNum, (endTime - startTime) / 1000000.0);
    }
};

} // namespace NativeModule

#endif // MYAPPLICATION_ARKUICUSTOMNODE_H
